package com.zj.docker.controller;

import com.google.common.collect.ImmutableList;
import com.spotify.docker.client.exceptions.DockerException;
import com.spotify.docker.client.messages.Volume;
import com.spotify.docker.client.messages.VolumeList;
import com.zj.docker.component.DockerComponent;
import com.zj.docker.component.UserRoleAuthentication;
import com.zj.docker.domain.Containers;
import com.zj.docker.domain.Volumes;
import com.zj.docker.enums.CommonEnum;
import com.zj.docker.enums.RoleEnum;
import com.zj.docker.service.ContainersService;
import com.zj.docker.service.VolumesService;
import com.zj.docker.utils.ListPagingUtils;
import com.zj.docker.utils.ResultVoUtil;
import com.zj.docker.utils.SFTPUtils;
import com.zj.docker.vo.ResultVo;
import com.zj.docker.vo.VolumesVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Objects;

/**
 * @Auther: zj
 * @Date: 2018/12/12 14:45
 * @Description:
 */
@RestController
@Slf4j
public class VolumeController {
    @Autowired
    UserRoleAuthentication userRoleAuthentication;
    @Autowired
    DockerComponent docker;
    @Autowired
    VolumesService volumesService;
    @Autowired
    ContainersService containersService;

    @Value("${sftp.ip}")
    private String SFTP_ADDRESS; //ip

    @Value("${sftp.port}")
    private Integer SFTP_PORT; //port

    @Value("${sftp.username}")
    private String SFTP_USERNAME; //sftp username

    @Value("${sftp.password}")
    private String SFTP_PASSWORD; //sftp password


    /**
     * 获取本地所有数据卷,需要管理员权限
     * @param request
     * @return
     * @throws DockerException
     * @throws InterruptedException
     */
    @GetMapping("/admin/getAllLocalVolumes")
    public ResultVo adminGetAllLocalVolumes(HttpServletRequest request) throws DockerException, InterruptedException {
        //鉴权
        String username = userRoleAuthentication.getUsernameAndAutenticateUserRoleFromRequest( request, RoleEnum.Admin.getMessage() );
        if (Objects.equals( username, CommonEnum.FALSE.getMessage())) {
            return ResultVoUtil.error();
        }

        VolumeList volumeList = docker.getThisDockerClient().listVolumes();

        return ResultVoUtil.success( volumeList );
    }

    /**
     * 打扫数据卷，管理员权限
     * @param request
     * @return
     * @throws DockerException
     * @throws InterruptedException
     */
    @GetMapping("/admin/removeVolumesWhenContainerIsNotExisted")
    public ResultVo adminRemoveVolumesWhenContainerIsNotExisted(HttpServletRequest request) throws DockerException, InterruptedException {
        //鉴权
        String username = userRoleAuthentication.getUsernameAndAutenticateUserRoleFromRequest( request, RoleEnum.Admin.getMessage() );
        if (Objects.equals( username, CommonEnum.FALSE.getMessage())) {
            return ResultVoUtil.error();
        }

        VolumeList volumeList = docker.getThisDockerClient().listVolumes();
        ImmutableList<Volume> volumes = volumeList.volumes();

        for(Volume volume : volumes) {
            Volumes volumes1 =volumesService.SelectOneByVolumeName( volume.name() );
            try {
                //如果数据卷对应的容器不存在，会清除相应的多余数据卷，以减小服务器的压力
                Containers containers1 = containersService.findOneByContainerId( volumes1.getContainerId() );
            }catch (Exception e) {
                log.warn("数据卷查不到对应的容器，异常位置：{}，错误信息：{}", "VolumesController.adminRemoveVolumesWhenContainerIsNotExisted",
                        e.getMessage());

                try {
                    docker.getThisDockerClient().removeVolume( volume.name() );
                }catch (Exception e1){
                    log.warn("数据卷无法删除，异常位置：{}，错误信息：{}", "VolumesController.adminRemoveVolumesWhenContainerIsNotExisted",
                            e1.getMessage());
                    continue;
                }

            }
        }
        return ResultVoUtil.success("数据卷打扫完成");
    }

    //分页，列出某一容器所有数据卷,普通用户权限
    @GetMapping("/customer/listAllVolumesFromContainer")
    public ResultVo customerListAllVolumesFromContainer(HttpServletRequest request,
                                                        @RequestParam("containerId") String containerId,
                                                        @RequestParam(value = "pageIndex",required = false,defaultValue ="1") Integer pageIndex ) {
        //鉴权
        String username = userRoleAuthentication.getUsernameAndAutenticateUserRoleFromRequest( request, RoleEnum.User.getMessage() );
        if (Objects.equals( username, CommonEnum.FALSE.getMessage())) {
            return ResultVoUtil.error();
        }
        List<Volumes> volumes = volumesService.SelectAllByContainerId( containerId,pageIndex-1 ).getContent();
        return ResultVoUtil.success(volumes);
    }

    /**
     * 上传文件到数据卷,普通用户权限
     * @param request
     * @param name 数据卷的名称
     * @param file 上传的文件
     * @return
     * @throws Exception
     */
    @PostMapping("/customer/uploadDocToVolume")
    public ResultVo customerUploadDocToVolume(HttpServletRequest request,
                                              @RequestParam("name") String name,
                                              @RequestParam("file") MultipartFile file
                                              ) throws Exception {
        //鉴权
        String username = userRoleAuthentication.getUsernameAndAutenticateUserRoleFromRequest( request, RoleEnum.User.getMessage() );
        if (Objects.equals( username, CommonEnum.FALSE.getMessage())) {
            return ResultVoUtil.error();
        }
        //校验参数
        if (StringUtils.isBlank( name )||file==null ) {
            return ResultVoUtil.error(CommonEnum.PARAM_ERROR.getMessage());
        }

        String bashPath ="/var/lib/docker/volumes/";
        String picSavePath = "/"+name+"/_data";


        SFTPUtils sftpUtils = new SFTPUtils( SFTP_ADDRESS,SFTP_PORT,SFTP_USERNAME,SFTP_PASSWORD);
        //上传文件，同步
        sftpUtils.uploadFile( file.getOriginalFilename(),bashPath+picSavePath,file );

        return ResultVoUtil.success("上传文件成功");
    }

    /**
     * 获取当前用户 所有的数据卷，普通用户权限
     * @param request
     * @param pageIndex
     * @return
     */
    @GetMapping("/customer/getAllSelfVolumes")
    public ResultVo customerGetAllSelfVolumes(HttpServletRequest request,
                                              @RequestParam("pageIndex") Integer pageIndex) {
        //鉴权
        String username = userRoleAuthentication.getUsernameAndAutenticateUserRoleFromRequest( request, RoleEnum.User.getMessage() );
        if (Objects.equals( username, CommonEnum.FALSE.getMessage())) {
            return ResultVoUtil.error();
        }
        List<VolumesVo> list = volumesService.SelectAllVolumesByAuthor( username );

        List<Object> list1 = ListPagingUtils.getPaging( list,pageIndex-1,5 );

        return ResultVoUtil.success(list1);

    }

    /**
     * 获取当前用户 所有数据卷的数量，普通用户权限
     * @param request request
     * @return size
     */
    @GetMapping("/customer/getAllSelfVolumesTotal")
    public ResultVo customerGetAllSelfVolumesTotal(HttpServletRequest request) {
        //鉴权
        String username = userRoleAuthentication.getUsernameAndAutenticateUserRoleFromRequest( request, RoleEnum.User.getMessage() );
        if (Objects.equals( username, CommonEnum.FALSE.getMessage())) {
            return ResultVoUtil.error();
        }

        List<VolumesVo> list = volumesService.SelectAllVolumesByAuthor( username );


        return ResultVoUtil.success(list.size());

    }

    /**
     * 获取所有数据卷，管理员权限
     * @param request request
     * @param pageIndex 页码
     * @return 所有数据卷
     */
    @GetMapping("/admin/getAllVolumes")
    public ResultVo adminGetAllVolumes(HttpServletRequest request,
                                       @RequestParam("pageIndex") Integer pageIndex) {
        //鉴权
        String username = userRoleAuthentication.getUsernameAndAutenticateUserRoleFromRequest( request, RoleEnum.Admin.getMessage() );
        if (Objects.equals( username, CommonEnum.FALSE.getMessage())) {
            return ResultVoUtil.error();
        }

        List<Volumes> list =volumesService.SelectAllVolumes( pageIndex-1 ).getContent();
        return ResultVoUtil.success(list);
    }

    /**
     * 获取所有数据卷的数量，管理员权限
     * @param request request
     * @return size
     */
    @GetMapping("/admin/getAllVolumesTotal")
    public ResultVo adminGetAllVolumes(HttpServletRequest request) {
        //鉴权
        String username = userRoleAuthentication.getUsernameAndAutenticateUserRoleFromRequest( request, RoleEnum.Admin.getMessage() );
        if (Objects.equals( username, CommonEnum.FALSE.getMessage())) {
            return ResultVoUtil.error();
        }
        List<Volumes> list =volumesService.SelectAllVolumes();
        return ResultVoUtil.success(list.size());
    }

}
